﻿using System;
using MediatR;
using Casamiel.Infrastructure;
using Casamiel.Domain;
using Casamiel.Domain.Response;
using System.Threading.Tasks;
using System.Threading;
using System.Linq;

using Enyim.Caching;
using Casamiel.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Casamiel.Domain.Entity;
using System.Data.SqlClient;
using System.Net.Http;
using Microsoft.Extensions.Options;
using Casamiel.Common.Extensions;

namespace Casamiel.Application.Commands.IC
{
	/// <summary>
	/// 
	/// </summary>
	public sealed class CardMergeCommandHandler : BaseCommandHandler, IRequestHandler<CardMergeCommand, BaseResult<string>>
	{
		private readonly IMemberCardService _memberCardService;
		private readonly IMemcachedClient _memcachedClient;
		private readonly IMemberCardRepository _memberCardRepository;
		private readonly IMemberService _memberService;
		private readonly string _memcachedPrex;
		private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("BizInfo");
		private readonly IUserLogService _userLogService;

		public CardMergeCommandHandler(INetICService netICService, IHttpClientFactory httpClientFactory, IOptionsSnapshot<CasamielSettings> settings, IMemberCardService memberCardService,
			IMemberCardRepository memberCardRepository, IMemcachedClient memcachedClient,
			  IMemberService memberService, IUserLogService userLogService) : base(netICService, httpClientFactory, settings)
		{
			_memberCardService = memberCardService;
			_memberCardRepository = memberCardRepository;
			_memcachedClient = memcachedClient;

			_memberService = memberService;
			_userLogService = userLogService;
			_memcachedPrex = settings.Value.MemcachedPre;
		}

		public async Task<BaseResult<string>> Handle(CardMergeCommand request, CancellationToken cancellationToken)
		{
			if (request is null) {
				throw new ArgumentNullException(nameof(request));
			}

			var giftcardinfo = await _memberCardRepository.FindAsync<ICasaMielSession>(request.Mobile, true).ConfigureAwait(false);
			if (giftcardinfo == null) {
				return new BaseResult<string>("", 9999, "礼品卡不存在");
			}

			var _cachekey = _memcachedPrex + Constant.CARDMERGE + request.Mobile;

			var trynum = _memcachedClient.Increment(_cachekey, 1, 1);

			if (trynum > 1) {
				//logger.Trace($"MemberIcselfregistCommand:{JsonConvert.SerializeObject(trynum)},{_cachekey}");
				//var newcard = cardlist.SingleOrDefault(c => c.IsBind == true && (c.CardType == "2" || c.CardType == "1"));
				if (giftcardinfo.IsBind == false) {
					return new BaseResult<string>("", 0, "");
				}

				//    return new Zmodel { Code = 0, Msg = "会员卡申请成功" };//, content = new { cardno = newcard.CardNo } };//, cardno = newcard.CardNo };
				//}
				if (trynum > 20) {
					_memcachedClient.Remove(_cachekey);
				}
				return new BaseResult<string>("", 999, "请重试");
			}
			var memberInfo = await _memberService.FindAsync<ICasaMielSession>(request.Mobile).ConfigureAwait(false);

			var cardinfo = await _memberCardRepository.FindAsync<ICasaMielSession>(request.Mobile, false).ConfigureAwait(false);
			if (cardinfo == null || cardinfo.IsBind == false) {
				ICResult result;
				try {
					var sex = "0";
					if (memberInfo != null) {
						if (memberInfo.Sex.HasValue) {
							if (memberInfo.Sex.Value == 1) {
								sex = "1";
							}
						}
					}
					result = await NetICService.Icselfregist(request.Mobile, $"{request.Source}099".ToInt32(0), 0, sex).ConfigureAwait(false);
				} catch (Exception) {
					_memcachedClient.Remove(_cachekey);
					throw;
				}
				var rnt = JsonConvert.DeserializeObject<JObject>(result.content);
				if (result.code == 0 || result.code == 31) {
					var mcard = await _memberCardService.FindAsync<ICasaMielSession>(rnt["cardno"].ToString(), request.Mobile).ConfigureAwait(false);
					if (mcard == null) {
						mcard = new MemberCard {
							M_ID = memberInfo.ID,
							CardNO = rnt["cardno"].ToString(),
							Mobile = request.Mobile,
							IsBind = true,
							CardType = "2",
							BindTime = DateTime.Now,
							Source = request.Source,
							CreateTime = DateTime.Now
						};

						try {
							await _memberCardService.AddAsync<ICasaMielSession>(mcard).ConfigureAwait(false);
							//await _memberCard.UnitOfWork.SaveEntitiesAsync();
							var logdata = new UserLog { Url = request.RequestUrl, OPInfo = $"申请会员卡,卡号:[{rnt["cardno"].ToString()}]", OPTime = DateTime.Now, UserName = request.Mobile, UserIP = request.UserIp };
							await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
						} catch (SqlException ex) {
							_memcachedClient.Remove(_cachekey);
							if (ex.Number != 2601) {
								throw;
							}
						}
					} else {
						mcard.IsBind = true;
						mcard.M_ID = memberInfo.ID;
						mcard.BindTime = DateTime.Now;
						mcard.Source = request.Source;
						await _memberCardService.UpdateAsync<ICasaMielSession>(mcard).ConfigureAwait(false);
						//await _memberCard.UnitOfWork.SaveChangesAsync();
						var logdata = new UserLog { Url = request.RequestUrl, OPInfo = $"重新申请会员卡,卡号:[{rnt["cardno"].ToString()}]", OPTime = DateTime.Now, UserName = request.Mobile, UserIP = request.UserIp };
						await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
					}
					//_memcachedClient.Remove(_cachekey);
					cardinfo = mcard;
					// return new Zmodel { Code = 0, Msg = "会员卡申请成功" };// content = new { cardno = mcard.CardNo }, cardno = mcard.CardNo });
				} else {
					_memcachedClient.Remove(_cachekey);
					return new BaseResult<string>("", 999, "出错啦");
				}
				//_memcachedClient.Remove(_cachekey);

			}
			if (cardinfo.CardNO == "0") {
				cardinfo = await _memberCardRepository.FindAsync<ICasaMielSession>(request.Mobile, false).ConfigureAwait(false);
			}

			var rsp = await NetICService.ICtransfer(new Domain.Request.IC.ICTransferRequest { Cardno = cardinfo.CardNO, Cardnosource = giftcardinfo.CardNO, Transfermoney = 0 }).ConfigureAwait(false);
			if (rsp.code == 0 || rsp.code == 209) {
				giftcardinfo.IsBind = false;
				await _memberCardService.UpdateAsync<ICasaMielSession>(giftcardinfo).ConfigureAwait(false);
				Task task = Task.Run(async () => {
					var logdata = new UserLog { Url = request.RequestUrl, OPInfo = $"卡合并：卡号:[{giftcardinfo.CardNO},{cardinfo.CardNO}]", OPTime = DateTime.Now, UserName = request.Mobile, UserIP = request.UserIp };
					await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
				},cancellationToken);
				_memcachedClient.Remove(_cachekey);
				return new BaseResult<string>("", 0, "");
			} else {
				_memcachedClient.Remove(_cachekey);
				logger.Error($"{giftcardinfo.CardNO},{JsonConvert.SerializeObject(rsp)}");
			}
			return new BaseResult<string>("", rsp.code, rsp.msg);
		}
	}
}
